﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AutomatasPrj
{
    class RegExp
    {
        private String regexp = "";
        private AFNDEpsilon afndEpsilon;

        public RegExp(String regexp)
        {
            this.regexp = regexp;
        }

        private void Parse()
        {
            foreach (char c in regexp)
            {
            }

            //this.afndEpsilon = ..
        }

        private Boolean Accepts(String s)
        {
            return afndEpsilon.Accepts(s);
        }

        private AFNDEpsilon Concatenation(AFNDEpsilon r, AFNDEpsilon s)
        {
            DeltaAFND delta = new DeltaAFND();

            delta.AddValues(r.Delta);
            delta.AddValues(s.Delta);

            // Conectar todos los finales de r al inicial de s, usando epsilons
            foreach (Estado final in r.Finales)
            {
                delta.AddValue(final, '\0', s.Inicial);
            }

            AFNDEpsilon afndEpsilon = new AFNDEpsilon(r.Inicial, estados, delta, s.Finales);

            return afndEpsilon;
        }

        private AFNDEpsilon Union(AFNDEpsilon r, AFNDEpsilon s)
        {
            DeltaAFND delta = new DeltaAFND();

            delta.AddValues(r.Delta);
            delta.AddValues(s.Delta);

            // Nuevo inicial y final
            Estado inicial = new Estado("");
            Estado final = new Estado("");

            // Un inicial global va hacia los dos iniciales
            delta.AddValue(inicial, '\0', r.Inicial);
            delta.AddValue(inicial, '\0', s.Inicial);

            // Los finales de ambos van hacia un final global
            foreach (Estado f in r.Finales)
            {
                delta.AddValue(f, '\0', final);
            }

            foreach (Estado f in s.Finales)
            {
                delta.AddValue(f, '\0', final);
            }

            AFNDEpsilon afndEpsilon = new AFNDEpsilon(inicial, estados, delta, new Estado[] { final });

            return afndEpsilon;
        }

        private AFNDEpsilon KleeneStar(AFNDEpsilon r)
        {
            DeltaAFND delta = new DeltaAFND();

            delta.AddValues(r.Delta);

            // Nuevo inicial y final
            Estado inicial = new Estado("");
            Estado final = new Estado("");

            // Un inicial global va hacia el inicial local y tb al final global
            delta.AddValue(inicial, '\0', r.Inicial);
            delta.AddValue(inicial, '\0', final);

            // Los finales van al final global y al inicial local
            foreach (Estado f in r.Finales)
            {
                delta.AddValue(f, '\0', final);
                delta.AddValue(f, '\0', r.Inicial);
            }

            AFNDEpsilon afndEpsilon = new AFNDEpsilon(inicial, estados, delta, new Estado[] { final });

            return afndEpsilon;
        }


    }
}
